#include "mytcpsocket.h"
#include"dboperate.h"
#include"mytcpserver.h"
#include<QDebug>

MyTcpSocket::MyTcpSocket()
{
    m_uploadFile = new TransFile;
    m_uploadFile->bTransform = false; // 默认不是在上传文件
    m_pDownloadFile = new QFile;
    m_pTimer = new QTimer;
    connect(this,SIGNAL(readyRead()),this,SLOT(recvMsg()));
    connect(this, SIGNAL(disconnected()), this, SLOT(handleClientOffline()));
    connect(m_pTimer, SIGNAL(timeout()), this, SLOT(handledownloadFileData())); // 关联计时器倒计时

}
QString MyTcpSocket::getStrName()
{
    return m_strName;
}

PDU* handleRegistRequest(PDU* pdu)
{
    char caName[32] = {'\0'};
    char caPwd[32] = {'\0'};
    strncpy(caName, pdu -> caData, 32);
    strncpy(caPwd, pdu -> caData + 32, 32);
    bool ret = dboperate::getInstance().handleRegist(caName, caPwd); // 处理请求，插入数据库

    // 响应客户端
    PDU *resPdu = mkPDU(0); // 响应消息
    resPdu -> uiMsgType = ENUM_MSG_TYPE_REGIST_RESPOND;
    if(ret)
    {
        strcpy(resPdu -> caData, REGIST_OK);
        QDir dir;
        ret = dir.mkdir(QString("./%1").arg(caName));
        qDebug() << "创建新用户文件夹" << ret;
    }
    if(!ret)
    {
        strcpy(resPdu -> caData, REGIST_FAILED);
    }

    return resPdu;
}
PDU* handleLoginRequest(PDU* pdu, QString& m_strName)
{
    char caName[32] = {'\0'};
    char caPwd[32] = {'\0'};
    strncpy(caName, pdu -> caData, 32);
    strncpy(caPwd, pdu -> caData + 32, 32);
    // qDebug() << pdu -> uiMsgType << " " << caName << " " << caPwd;
    bool ret = dboperate::getInstance().handleLogin(caName, caPwd);
    QString strUserRootPath;
    // 响应客户端
    PDU *resPdu = NULL; // 响应消息
    if(ret){
             strUserRootPath = QString("./%1").arg(caName);
             resPdu = mkPDU(strUserRootPath.size() + 1);
             resPdu->uiMsgType = ENUM_MSG_TYPE_LOGIN_RESPOND;

             memcpy(resPdu -> caData, LOGIN_OK, 32);
             memcpy(resPdu -> caData + 32, caName, 32);
             strncpy((char*)resPdu->caMsg, strUserRootPath.toStdString().c_str(), strUserRootPath.size() + 1);

             m_strName =caName;
             qDebug() << "登录成功，用户根路径：" << strUserRootPath;
         }else {
             resPdu = mkPDU(0);
             resPdu->uiMsgType = ENUM_MSG_TYPE_LOGIN_RESPOND;
             strcpy(resPdu->caData, LOGIN_FAILED);
             qDebug() << "登录失败，用户名或密码错误";
         }
    qDebug() << "登录处理：" << resPdu -> uiMsgType << " " << resPdu ->caData << " " << resPdu ->caData + 32;

    return resPdu;
}
PDU* handleOnlineUsersRequest()
{
    QStringList strList = dboperate::getInstance().handleOnlineUsers();
    uint uiMsgLen = strList.size() * 32;
    PDU *resPdu = mkPDU(uiMsgLen);
    resPdu -> uiMsgType = ENUM_MSG_TYPE_ONLINE_USERS_RESPOND;
    for(int i = 0; i < strList.size(); ++ i)
    {
        memcpy((char*)(resPdu -> caMsg) + 32 * i, strList[i].toStdString().c_str(), strList[i].size());
    }

    return resPdu;
}
PDU* handleAddFriendRequest(PDU* pdu)
{
    char addedName[32] = {'\0'};
    char sourceName[32] = {'\0'};
    strncpy(addedName, pdu -> caData, 32);
    strncpy(sourceName, pdu -> caData + 32, 32);
    // qDebug() << "handleAddFriendRequest  " << addedName << " " << sourceName;
    int iSearchUserStatus = dboperate::getInstance().handleAddFriend(addedName, sourceName);
    PDU* resPdu = NULL;

    switch (iSearchUserStatus) {
    case 0: // 0对方存在不在线
    {
        resPdu = mkPDU(0);
        resPdu -> uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_RESPOND;
        strcpy(resPdu -> caData, ADD_FRIEND_OFFLINE);
        break;
    }
    case 1: // 1对方存在在线
    {
        // 需要转发给对方请求添加好友消息
        MyTcpServer::getInstance().forwardMsg(addedName, pdu);

        resPdu = mkPDU(0);
        resPdu -> uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_RESPOND;
        strcpy(resPdu -> caData, ADD_FRIEND_OK); // 表示加好友请求已发送
        break;
    }
    case 2: // 2用户不存在
    {
        resPdu = mkPDU(0);
        resPdu -> uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_RESPOND;
        strcpy(resPdu -> caData, ADD_FRIEND_EMPTY);
        break;
    }
    case 3: // 3已是好友
    {
        resPdu = mkPDU(0);
        resPdu -> uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_RESPOND;
        strcpy(resPdu -> caData, ADD_FRIEND_EXIST);
        break;
    }
    case 4: // 4请求错误
    {
        resPdu = mkPDU(0);
        resPdu -> uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_RESPOND;
        strcpy(resPdu -> caData, UNKNOWN_ERROR);
        break;
    }
    default:
        break;
    }

    return resPdu;
}
void handleAddFriendAgree(PDU* pdu)
{
    char addedName[32] = {'\0'};
    char sourceName[32] = {'\0'};
    strncpy(addedName, pdu -> caData, 32);
    strncpy(sourceName, pdu -> caData + 32, 32);

    dboperate::getInstance().handleAddFriendAgree(addedName, sourceName);
    MyTcpServer::getInstance().forwardMsg(sourceName, pdu);
}
void handleAddFriendReject(PDU* pdu)
{
    char sourceName[32] = {'\0'};
    strncpy(sourceName, pdu -> caData + 32, 32);
    MyTcpServer::getInstance().forwardMsg(sourceName, pdu);
}
// 刷新好友列表请求
PDU* handleFlushFriendRequest(PDU* pdu)
{
    char caName[32] = {'\0'};

    strncpy(caName, pdu -> caData, 32);

    QStringList strList = dboperate::getInstance().handleFlushFriend(caName);
    uint uiMsgLen = strList.size() / 2 * 36; // 36 char[32] 好友名字+ 4 int 在线状态

    PDU* resPdu = mkPDU(uiMsgLen);
    resPdu -> uiMsgType = ENUM_MSG_TYPE_FLUSH_FRIEND_RESPOND;
    for(int i = 0; i * 2 < strList.size(); ++ i)
    {
        strncpy((char*)(resPdu -> caMsg) + 36 * i, strList.at(i * 2).toStdString().c_str(), 32);
        strncpy((char*)(resPdu -> caMsg) + 36 * i + 32, strList.at(i * 2 + 1).toStdString().c_str(), 4);
    }

    return resPdu;
}
PDU* handleDeleteFriendRequest(PDU* pdu)
{
    char deletedName[32] = {'\0'};
    char sourceName[32] = {'\0'};
    // 拷贝读取的信息
    strncpy(deletedName, pdu -> caData, 32);
    strncpy(sourceName, pdu -> caData + 32, 32);
    bool ret = dboperate::getInstance().handleDeleteFriend(deletedName, sourceName);

    // 给请求删除方消息提示，以返回值形式
    PDU *resPdu = mkPDU(0);
    resPdu -> uiMsgType = ENUM_MSG_TYPE_DELETE_FRIEND_RESPOND;
    if(ret)
    {
        strncpy(resPdu -> caData, DEL_FRIEND_OK, 32);
    }
    else
    {
        strncpy(resPdu -> caData, DEL_FRIEND_FAILED, 32);
    }

    // 给被删除方消息提示，如果在线的话
    MyTcpServer::getInstance().forwardMsg(deletedName, pdu);

    return resPdu;
}
PDU* handlePrivateChatRequest(PDU* pdu)
{
    char chatedName[32] = {'\0'};
    char sourceName[32] = {'\0'};
    char strSendMsg[256] = {'\0'};

    if (pdu->uiPDULen < sizeof(PDU) || pdu->uiMsgLen > sizeof(strSendMsg)) {
        qDebug() << "Received PDU too small or message length exceeds buffer.";
        return 0;
    }

    strncpy(chatedName, pdu->caData, 32); // 复制目标用户名
    chatedName[31] = '\0';
    strncpy(sourceName, pdu->caData + 32, 32); // 复制请求方用户名
    sourceName[31] = '\0';

    memcpy(strSendMsg, pdu->caMsg, pdu->uiMsgLen); // 复制消息内容
    strSendMsg[pdu->uiMsgLen] = '\0';

    qDebug() << "handlePrivateChatRequest:" << "Chated Name:" << chatedName << " Source Name:" << sourceName << " Message:" << strSendMsg;
    PDU* resPdu = NULL;
    bool ret = MyTcpServer::getInstance().forwardMsg(chatedName, pdu);

    if (!ret) { // 0对方不在线
        resPdu = mkPDU(0);
        if (resPdu == NULL) {
            qDebug() << "Failed to allocate memory for response PDU.";
            return 0;
        }
        resPdu->uiMsgType = ENUM_MSG_TYPE_PRIVATE_CHAT_RESPOND;
        strcpy(resPdu->caData, PRIVATE_CHAT_OFFLINE);
    }

    return resPdu;
}
//创建文件夹请求处理
PDU* handleCreateDirRequest(PDU* pdu)
{
    char caDirName[32];
    char caCurPath[pdu -> uiMsgLen];
    strncpy(caDirName, pdu -> caData, 32);
    strncpy(caCurPath, (char*)pdu -> caMsg, pdu -> uiMsgLen);

    qDebug() << "接收到的当前路径:" << caCurPath;

    QString strDir = QString("%1/%2").arg(caCurPath).arg(caDirName);
    QDir dir;
    PDU *resPdu = mkPDU(0);
    resPdu -> uiMsgType = ENUM_MSG_TYPE_CREATE_DIR_RESPOND;

    qDebug() << "创建文件夹：" << strDir;
    if(dir.exists(caCurPath)) // 路径存在
    {
        if(dir.exists(strDir)) // 文件夹已经存在
        {
            strncpy(resPdu -> caData, CREATE_DIR_EXIST, 32);
        }
        else
        {
            dir.mkdir(strDir); // 创建文件夹
            strncpy(resPdu -> caData, CREATE_DIR_OK, 32);
        }
    }
    else // 路径不存在
    {
        strncpy(resPdu -> caData, PATH_NOT_EXIST, 32);
    }

    return resPdu;

}

//刷新
PDU* handleFlushDirRequest(PDU* pdu)
{
    char caCurDir[pdu -> uiMsgLen];
    memcpy(caCurDir, (char*)pdu -> caMsg, pdu -> uiMsgLen);
    qDebug() << "刷新文件夹：" << caCurDir;
    QDir dir;
    PDU* resPdu = NULL;

    if(!dir.exists(caCurDir)) // 请求文件夹不存在
    {
        resPdu = mkPDU(0);
        strncpy(resPdu -> caData, PATH_NOT_EXIST, 32);
    }
    else // 存在
    {
        dir.setPath(caCurDir); // 设置为当前目录
        QFileInfoList fileInfoList = dir.entryInfoList(); // 获取当前目录下所有文件
        int iFileNum = fileInfoList.size();

        resPdu = mkPDU(sizeof(FileInfo) * iFileNum);
        FileInfo *pFileInfo = NULL; // 创建一个文件信息结构体指针，方便之后遍历PDU空间来赋值
        strncpy(resPdu -> caData, FLUSH_DIR_OK, 32);

        for(int i = 0; i < iFileNum; i++)
        {
            pFileInfo = (FileInfo*)(resPdu -> caMsg) + i; // 通过指针指向，直接修改PDU空间值，每次偏移FileInfo大小
            memcpy(pFileInfo -> caName, fileInfoList[i].fileName().toStdString().c_str(), fileInfoList[i].fileName().size());
            pFileInfo -> bIsDir = fileInfoList[i].isDir();
            pFileInfo -> uiSize = fileInfoList[i].size();
            qDebug() << "文件信息：" << pFileInfo -> caName << " " << pFileInfo -> bIsDir << " " ;
        }
    }
    resPdu -> uiMsgType = ENUM_MSG_TYPE_FLUSH_DIR_RESPOND;
    qDebug() <<resPdu -> uiMsgType;
    return resPdu;
}

// 删除文件或文件夹处理
PDU* handleDelFileOrDirRequest(PDU* pdu)
{
    PDU* resPdu = mkPDU(0);
    char strDelPath[pdu -> uiMsgLen];
    memcpy(strDelPath, (char*)pdu -> caMsg, pdu -> uiMsgLen);
    qDebug() << "删除文件：" << strDelPath;
    QDir dir;

    resPdu -> uiMsgType = ENUM_MSG_TYPE_DELETE_FILE_RESPOND;
    if(!dir.exists(strDelPath)) // 路径不存在
    {
        strncpy(resPdu -> caData, PATH_NOT_EXIST, 32);
    }
    else
    {
        bool ret = false;

        QFileInfo fileInfo(strDelPath);
        if(fileInfo.isDir()) // 是文件目录
        {
            dir.setPath(strDelPath);
            ret = dir.removeRecursively();
        }
        else if(fileInfo.isFile())
        {
            ret = dir.remove(strDelPath);
        }
        if(ret)
        {
            strncpy(resPdu -> caData, DELETE_FILE_OK, 32);
        }
        else
        {
            strncpy(resPdu -> caData, DELETE_FILE_FAILED, 32);
        }
    }
    qDebug() << resPdu -> caData;

    return resPdu;
}

// 重命名文件或文件夹请求处理
PDU* handleRenameFileRequest(PDU* pdu)
{
    PDU* resPdu = mkPDU(0);
    char caCurPath[pdu -> uiMsgLen];
    char caOldName[32]; // 旧文件名
    char caNewName[32]; // 新文件名
    memcpy(caCurPath, (char*)pdu -> caMsg, pdu -> uiMsgLen);
    strncpy(caOldName, pdu -> caData, 32);
    strncpy(caNewName, pdu -> caData + 32, 32);
    qDebug() << "重命名文件：" << caCurPath << " " << caOldName << " -> " << caNewName;
    QDir dir;

    resPdu -> uiMsgType = ENUM_MSG_TYPE_RENAME_FILE_RESPOND;
    dir.setPath(caCurPath);
    if(dir.rename(caOldName, caNewName))
    {
        strncpy(resPdu -> caData, RENAME_FILE_OK, 32);
    }
    else
    {
        strncpy(resPdu -> caData, RENAME_FILE_FAILED, 32);
    }
    qDebug() << resPdu -> caData;

    return resPdu;
}

// 进入文件夹请求处理
PDU* handleEntryDirRequest(PDU* pdu)
{
    char strEntryPath[pdu -> uiMsgLen]; // 进入文件夹路径
    memcpy(strEntryPath, (char*)pdu -> caMsg, pdu -> uiMsgLen);
    qDebug() << "进入 " << strEntryPath;
    PDU* resPdu = NULL;
    QDir dir(strEntryPath);

    if(!dir.exists()) // 请求文件夹不存在
    {
        resPdu = mkPDU(0);
        strncpy(resPdu -> caData, PATH_NOT_EXIST, 32);
    }
    else // 存在
    {
        QFileInfo fileInfo(strEntryPath);
        if(!fileInfo.isDir()) // 不是文件夹
        {
            resPdu = mkPDU(0);
            strncpy(resPdu -> caData, ENTRY_DIR_FAILED, 32);
        }
        else
        {
            resPdu = handleFlushDirRequest(pdu); // 通过该函数获取文件夹下内容
            if (resPdu == nullptr)
            {
                resPdu = mkPDU(0);
                strncpy(resPdu->caData, FLUSH_DIR_FAILED, 32);
            }
        }
    }
    resPdu -> uiMsgType = ENUM_MSG_TYPE_ENTRY_DIR_RESPOND;
    qDebug() << "1 resPdu -> caData ：" << resPdu -> caData;
    if(strcmp(resPdu -> caData, FLUSH_DIR_OK) == 0)
    {
        strncpy(resPdu -> caData, ENTRY_DIR_OK, 32);
        qDebug() << "2 resPdu -> caData ：" << resPdu -> caData;
    }
    else
    {
        strncpy(resPdu -> caData, ENTRY_DIR_FAILED, 32);
        qDebug() << "2 resPdu -> caData ：" << resPdu -> caData;
    }

    return resPdu;
}

// 返回上一目录请求
PDU* handlePreDirRequest(PDU* pdu)
{
    char strPrePath[pdu -> uiMsgLen]; // 进入文件夹路径
    memcpy(strPrePath, (char*)pdu -> caMsg, pdu -> uiMsgLen);
    qDebug() << "上一目录： " << strPrePath;
    PDU* resPdu = NULL;
    QDir dir(strPrePath);

    if(!dir.exists()) // 请求文件夹不存在
    {
        resPdu = mkPDU(0);
        strncpy(resPdu -> caData, PATH_NOT_EXIST, 32);
    }
    else // 存在
    {
        resPdu = handleFlushDirRequest(pdu); // 通过该函数获取文件夹下内容
    }
    resPdu -> uiMsgType = ENUM_MSG_TYPE_PRE_DIR_RESPOND;
    qDebug() << "1 resPdu -> caData ：" << resPdu -> caData;
    if(strcmp(resPdu -> caData, FLUSH_DIR_OK) == 0)
    {
        strncpy(resPdu -> caData, PRE_DIR_OK, 32);
        qDebug() << "2 resPdu -> caData ：" << resPdu -> caData;
    }
    else
    {
        strncpy(resPdu -> caData, PRE_DIR_FAILED, 32);
        qDebug() << "2 resPdu -> caData ：" << resPdu -> caData;
    }

    return resPdu;
}
PDU* handleUploadFileRequest(PDU* pdu, TransFile* transFile)
{
    char caCurPath[pdu -> uiMsgLen];
    char caFileName[32] = {'\0'};
    qint64 fileSize = 0;

    strncpy(caCurPath, (char*)pdu -> caMsg, pdu -> uiMsgLen);
    sscanf(pdu -> caData, "%s %lld", caFileName, &fileSize);
    QString strFilePath = QString("%1/%2").arg(caCurPath).arg(caFileName); // 文件路径
    qDebug() << "上传文件路径：" << strFilePath;

    PDU* resPdu = mkPDU(0);
    resPdu -> uiMsgType = ENUM_MSG_TYPE_UPLOAD_FILE_RESPOND;

    transFile->file.setFileName(strFilePath); // 设置要上传的文件名
    qDebug() <<"设置成功";
    if(transFile->file.open(QIODevice::WriteOnly)) // 以只写的方式打开文件，文件如果不存在会自动创建
    {    qDebug() <<"打开文件成功";
        transFile->bTransform = true; // 正在上传文件状态
        transFile->iTotalSize = fileSize;
        transFile->iReceivedSize = 0;

        memcpy(resPdu -> caData, UPLOAD_FILE_START, 32);
        qDebug() <<resPdu -> caData;
    }
    else // 打开文件失败
    {
        memcpy(resPdu -> caData, UPLOAD_FILE_FAILED, 32);
    }

    return resPdu;
}


// 下载文件请求处理
PDU* handleDownloadFileRequest(PDU* pdu, QFile *fDownloadFile, QTimer *pTimer)
{
    char caFileName[32] = {'\0'};
    char caCurPath[pdu -> uiMsgLen];
    memcpy(caFileName, pdu -> caData, 32);
    memcpy(caCurPath, (char*)pdu -> caMsg, pdu -> uiMsgLen);
    QString strDownloadFilePath = QString("%1/%2").arg(caCurPath).arg(caFileName);
    fDownloadFile->setFileName(strDownloadFilePath);

    qDebug() << "下载文件：" << strDownloadFilePath;
    qint64 fileSize = fDownloadFile -> size();

    PDU *resPdu = NULL;
    if(fDownloadFile->open(QIODevice::ReadOnly))
    {
        resPdu = mkPDU(32 + sizeof (qint64) + 5);

        resPdu -> uiMsgType = ENUM_MSG_TYPE_DOWNLOAD_FILE_RESPOND;
        strncpy(resPdu -> caData, DOWNLOAD_FILE_START, 32);
        sprintf((char*)resPdu -> caMsg, "%s %lld", caFileName, fileSize);
        pTimer -> start(1000); // 开始计时器1000ms
        qDebug() << (char*)resPdu -> caMsg;
    }
    else // 打开文件失败
    {
        resPdu = mkPDU(0);

        resPdu -> uiMsgType = ENUM_MSG_TYPE_DOWNLOAD_FILE_RESPOND;
        strncpy(resPdu -> caData, DOWNLOAD_FILE_FAILED, 32);
    }

    return resPdu;
}

void MyTcpSocket::recvMsg()
{
    if(m_uploadFile->bTransform)
      {
          // 接收数据
          QByteArray baBuffer = this -> readAll();
          m_uploadFile->file.write(baBuffer); // 文件在上一个请求已经打开了
          m_uploadFile->iReceivedSize += baBuffer.size();
          PDU* resPdu = NULL;

          qDebug() << "上传文件中：" << m_uploadFile->iReceivedSize;

          if(m_uploadFile->iReceivedSize == m_uploadFile->iTotalSize)
          {
              m_uploadFile->file.close(); // 关闭文件
              m_uploadFile->bTransform = false;

              resPdu = mkPDU(0);
              resPdu -> uiMsgType = ENUM_MSG_TYPE_UPLOAD_FILE_RESPOND;
              strncpy(resPdu -> caData, UPLOAD_FILE_OK, 32);
          }
          else if(m_uploadFile -> iReceivedSize > m_uploadFile->iTotalSize)
          {
              m_uploadFile->file.close(); // 关闭文件
              m_uploadFile->bTransform = false;

              resPdu = mkPDU(0);
              resPdu -> uiMsgType = ENUM_MSG_TYPE_UPLOAD_FILE_RESPOND;
              strncpy(resPdu -> caData, UPLOAD_FILE_FAILED, 32);
          }

          // 响应客户端
          if(NULL != resPdu)
          {
              // qDebug() << resPdu -> uiMsgType << " " << resPdu ->caData;
              this -> write((char*)resPdu, resPdu -> uiPDULen);
              // 释放空间
              free(resPdu);
              resPdu = NULL;
          }

          return ;
      }

    uint uiPDULen =0;
    this->read((char*)&uiPDULen,sizeof(uint));
    uint uiMsgLen =uiPDULen-sizeof (PDU);
    PDU *pdu = mkPDU(uiMsgLen);
    this->read((char*)pdu+sizeof(uint),uiPDULen-sizeof (uint));
    qDebug() << pdu->uiMsgType << pdu->caData;
    PDU* resPdu = NULL; // 响应报文
    switch (pdu->uiMsgType)
    {
    case ENUM_MSG_TYPE_REGIST_REQUEST:
    {
      resPdu = handleRegistRequest(pdu);
        break;
    }
    case ENUM_MSG_TYPE_LOGIN_REQUEST:
    {
        resPdu = handleLoginRequest(pdu, m_strName);
        break;
    }
    case ENUM_MSG_TYPE_ONLINE_USERS_REQUEST:
    {
        resPdu = handleOnlineUsersRequest();
        break;
    }
    case ENUM_MSG_TYPE_ADD_FRIEND_REQUEST:
    {
        resPdu = handleAddFriendRequest(pdu);
        break;
    }
    case ENUM_MSG_TYPE_ADD_FRIEND_AGREE: // 同意加好友
    {
        handleAddFriendAgree(pdu);
        break;
    }
    case ENUM_MSG_TYPE_ADD_FRIEND_REJECT: // 拒绝加好友
    {
        handleAddFriendReject(pdu);
        break;
    }
    case ENUM_MSG_TYPE_FLSUH_FRIEND_REQUEST:
    {      
        resPdu = handleFlushFriendRequest(pdu);
        break;
    }
    case ENUM_MSG_TYPE_DELETE_FRIEND_REQUEST: // 删除好友请求
    {
        resPdu = handleDeleteFriendRequest(pdu);

        break;
    }
    case ENUM_MSG_TYPE_PRIVATE_CHAT_REQUEST:
    {
        resPdu = handlePrivateChatRequest(pdu);
        break;
    }
    case ENUM_MSG_TYPE_CREATE_DIR_REQUEST: // 创建文件夹请求
       {
           resPdu = handleCreateDirRequest(pdu);
           break;
       }
    case ENUM_MSG_TYPE_FLUSH_DIR_REQUEST://刷新文件
    {
        resPdu = handleFlushDirRequest(pdu);
        break;
    }
    case ENUM_MSG_TYPE_DELETE_FILE_REQUEST://删除文件
    {
        resPdu = handleDelFileOrDirRequest(pdu);
        break;
    }
    case ENUM_MSG_TYPE_RENAME_FILE_REQUEST://重命名
    {
        resPdu = handleRenameFileRequest(pdu);
        break;
    }
    case ENUM_MSG_TYPE_ENTRY_DIR_REQUEST://进入
    {
        resPdu = handleEntryDirRequest(pdu);
        break;
    }
    case ENUM_MSG_TYPE_PRE_DIR_REQUEST: // 上一目录请求
    {
        resPdu = handlePreDirRequest(pdu);
        break;
    }
    case ENUM_MSG_TYPE_UPLOAD_FILE_REQUEST:
      {
        resPdu = handleUploadFileRequest(pdu, m_uploadFile);
          break;
      }
    case ENUM_MSG_TYPE_DOWNLOAD_FILE_REQUEST: // 下载文件请求
    {
        resPdu = handleDownloadFileRequest(pdu, m_pDownloadFile, m_pTimer);
        break;
    }
    default:
        break;
    }
    // 响应客户端
    if(NULL != resPdu)
    {   this -> write((char*)resPdu, resPdu -> uiPDULen);
        free(resPdu);
        resPdu = NULL;
    }
    free(pdu);
    pdu = NULL;

}

void MyTcpSocket::handleClientOffline()
{
    dboperate::getInstance().handleOffline(m_strName.toStdString().c_str());
    emit offline(this);
}

void MyTcpSocket::handledownloadFileData()
{
    m_pTimer->stop(); // 停止计时器
    // 循环传输数据
    char *pBuffer = new char[4096];
    qint64 iActualSize = 0; // 实际读取文件大小

    while(true)
    {
        iActualSize = m_pDownloadFile->read(pBuffer, 4096);
        if (iActualSize > 0 && iActualSize <= 4096)
        {
            this -> write(pBuffer, iActualSize);
        }
        else if (iActualSize == 0)
        { // 发送完成
            break;
        }
        else
        {
            qDebug() << "发送文件数据给客户端出错！";
            break;
        }
    }

    m_pDownloadFile -> close(); // 关闭文件
    delete [] pBuffer;
    pBuffer = NULL;
    m_pDownloadFile->setFileName(""); // 清除上传文件夹名，以免影响之后上传操作
}
